﻿
#region Using Directives.

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml.Linq;
using RWXMLEdit.Common;

#endregion

namespace RWXMLEdit.Client.Forms
{
    public partial class FormAddChild : Form
    {
        #region Fields.

        private XElement _xElement;
        private readonly string _railWorksPath = string.Empty;
        private string _newName = string.Empty;
        private List<string> _userValues;

        #endregion

        #region Constructors.

        public FormAddChild(string railworkspath, List<string> userValues)
        {
            InitializeComponent();

            _railWorksPath = railworkspath;

            _userValues = userValues;
        }

        #endregion

        #region Properties.

        public XElement GetXElement
        {
            get { return _xElement; }
        }

        public string GetNewName
        {
            get { return _newName; }
        }

        #endregion

        #region Events.

        private void btnSetPath_Click(object sender, EventArgs e)
        {
            txtChildName.Validating -= txtChildName_Validating;

            openFileDialog.Title = @"Set Blue Print XML File";
            openFileDialog.ReadOnlyChecked = false;
            openFileDialog.Filter = @"XML Files(*.xml)|*.xml|IGS Files(*.igs)|*.igs|IA Files(*.ia)|*.ia|ACE Files(*.ace)|*.ace|LUA Files(*.lua)|*.lua";
            openFileDialog.FilterIndex = 0;
            openFileDialog.InitialDirectory = _railWorksPath;
            openFileDialog.RestoreDirectory = true;
            openFileDialog.CheckFileExists = true;

            DialogResult open = openFileDialog.ShowDialog(this);

            if (open == DialogResult.OK)
            {
                

                string fullPath = openFileDialog.FileName;

                string partial = fullPath.Replace(_railWorksPath + Path.DirectorySeparatorChar, "");

                var separator = new [] {Path.DirectorySeparatorChar.ToString()};

                string[] folders = partial.Split(separator, 3, StringSplitOptions.None);

                string provider = folders[0];

                string product = folders[1];

                string bluePrint = folders[2];

                string childName = Path.GetFileNameWithoutExtension(fullPath);

                txtChildName.Text = childName;

                txtBluePrintID.Text = bluePrint;

                txtProvider.Text = provider;

                txtProduct.Text = product;

                txtChildName.SelectAll();

                txtChildName.Focus();
            }
            txtChildName.Validating += txtChildName_Validating;
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            string path = Path.Combine(txtBluePrintID.Text, "");

            _xElement = CreateNewChildElement(txtChildName.Text, txtProvider.Text, txtProduct.Text, path, string.Empty);

            _newName = txtChildName.Text;
        }

        private void txtChildName_TextChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtChildName.Text))
            {
                btnOK.Enabled = true;
            }
            else
            {
                btnOK.Enabled = false;
            }
        }

        private void txtChildName_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            errorProvider.SetIconAlignment(txtChildName, ErrorIconAlignment.MiddleLeft);

            if (ValidateNotEmpty(txtChildName.Text))
            {
                errorProvider.SetError(txtChildName, "");
            }
            else
            {
                errorProvider.SetError(txtChildName, "The ChildName element can not be blank!");
                return;
            }

            if (ValidateNotDuplicate(txtChildName.Text))
            {
                errorProvider.SetError(txtChildName, "");
            }
            else
            {
                errorProvider.SetError(txtChildName, "The ChildName already exists, need to be an unique name!");
            }
        }

        private void FormAddChild_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (DialogResult == DialogResult.Cancel)
                e.Cancel = false;
            else
            {
                if (errorProvider.GetError(txtChildName) != "")
                    e.Cancel = true;
            }
        }

        #endregion

        #region CreateElementChildName.


        private XElement CreateElementChildName(string childname)
        {
            var xattribute = new XAttribute("name", "ChildName");

            var xChildName = new XElement("Attribute", xattribute,
                                new XElement("cDeltaString",
                                    new XElement("Element", new XElement("Value", childname))));

            return xChildName;
        }

        #endregion

        #region CreateElementBluePrintId.

        private XElement CreateElementBluePrintId(string provider, string product, string blueprintid)
        {
            var xattribute = new XAttribute("name", "BlueprintID");

            var xBluePrintId = new XElement("Attribute", xattribute,
                                    new XElement("iBlueprintLibrary-cAbsoluteBlueprintID",
                                        new XElement("Element",
                                            new XElement("Value"))));

            xattribute = new XAttribute("name", "BlueprintSetID");

            var xBluePrintSetId = new XElement("Attribute", xattribute,
                                    new XElement("iBlueprintLibrary-cBlueprintSetID",
                                        new XElement("Element",
                                            new XElement("Value",
                                                new XElement("Attribute", new XAttribute("name", "Provider"),
                                                    new XElement("cDeltaString",
                                                        new XElement("Element",
                                                            new XElement("Value", provider)))),

                                                new XElement("Attribute", new XAttribute("name", "Product"),
                                                    new XElement("cDeltaString",
                                                        new XElement("Element",
                                                            new XElement("Value", product))))))));

            xattribute = new XAttribute("name", "BlueprintID");

            var xSubBluePrintId = new XElement("Attribute", xattribute,
                                    new XElement("cDeltaString",
                                        new XElement("Element",
                                            new XElement("Value", blueprintid))));

            var xElement = xBluePrintId.Element("iBlueprintLibrary-cAbsoluteBlueprintID");
            if (xElement != null)
            {
                var xElement1 = xElement.Element("Element");
                if (xElement1 != null)
                {
                    var xElement2 = xElement1.Element("Value");
                    if (xElement2 != null)
                        xElement2.Add(xBluePrintSetId, xSubBluePrintId);
                }
            }

            return xBluePrintId;
        }

        #endregion

        #region CreateElementMatrix.

        private XElement CreateElementMatrix()
        {
            var xattribute = new XAttribute("name", "Matrix");

            var xMatrix = new XElement("Attribute", xattribute,
                               new XElement("cHcRMatrix4x4",
                                   new XElement("Element",
                                       new XElement("Value"))));

            xattribute = new XAttribute("name", "Element");

            var xElement = new XElement("Attribute", xattribute,
                                new XElement("__Indexed__sFloat32",
                                    new XElement("Element",
                                        new XElement("Value"))));

            Functions.AddSFloat32Tags(ref xElement);

            var element = xMatrix.Element("cHcRMatrix4x4");
            if (element != null)
            {
                var element1 = element.Element("Element");
                if (element1 != null)
                {
                    var element2 = element1.Element("Value");
                    if (element2 != null) element2.Add(xElement);
                }
            }

            return xMatrix;
        }

        #endregion

        #region CreateElementParentNodeName.

        private XElement CreateElementParentNodeName    (string parentnodename)
        {
            var xattribute = new XAttribute("name", "ParentNodeName");

            var xParentNodeName = new XElement("Attribute", xattribute,
                                    new XElement("cDeltaString",
                                        new XElement("Element",
                                            new XElement("Value", parentnodename))));

            return xParentNodeName;
        }

        #endregion

        #region CreateNewChildElement.

        private XElement CreateNewChildElement(string childname, string provider, string product, string blueprintid, string parentnodename)
        {
            var xRoot = new XElement("cEntityContainerBlueprint-sChild",
                           new XElement("Element",
                               new XElement("Value")));

            var xChildName = CreateElementChildName(childname);
            var xBluePrintId = CreateElementBluePrintId(provider, product, blueprintid);
            var xMatrix = CreateElementMatrix();
            var xParentNodeName = CreateElementParentNodeName(parentnodename);
            
            var xElement = xRoot.Element("Element");
            if (xElement != null)
            {
                var xElement1 = xElement.Element("Value");
                if (xElement1 != null)
                {
                    xElement1.Add(xChildName);
                    xElement1.Add(xBluePrintId);
                    xElement1.Add(xMatrix);
                    xElement1.Add(xParentNodeName);
                }
            }

            return xRoot;
        }

        #endregion

        #region Validation.

        private bool ValidateNotEmpty(string validate)
        {
            return !string.IsNullOrEmpty(validate);
        }

        private bool ValidateNotDuplicate(string validate)
        {
            if (_userValues == null || _userValues.Count == 0)
                return true;

            return !_userValues.Contains(validate);
        }

        #endregion

        
    }
}
